package com.guanzhi.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * SpringBoot 实战
 * <p> Package: com.guanzhi.aop </p>
 * <p> File: MethodCallCountAspect.java </p>
 * <p> Description:  (AOP切面 统计方法调用次数)</p>
 * <p> Date: 2024/2/27 15:01</p>
 *
 * @author 观之
 * @version 1.0 （代码版本）
 * @email <a href="mailto:guanzhi55634@aliyun.com">观之</a>（邮箱）
 * @date 2024/2/27 15:01
 * @since jdk17（jdk版本）
 */
@Aspect
@Component
public class MethodCallCountAspect {

    /**
     * 用于存储方法调用次数的Map，使用ConcurrentMap保证线程安全
     */
    private final Map<String, AtomicInteger> counterMap = new ConcurrentHashMap<>();

    /**
     * 通过@Around(环绕通知)注解，指定在方法调用之前和之后执行
     */
    @Around("@annotation(com.guanzhi.annotation.MethodCallCountAnnotation)")
    public Object methodCallCountAspect(ProceedingJoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().toShortString();
        try {
            return joinPoint.proceed();
        } catch (Throwable ignored) {
            return null;
        } finally {
            AtomicInteger counter = counterMap.computeIfAbsent(methodName, k -> new AtomicInteger(0));
            counter.incrementAndGet();
            System.out.println("方法 {" + methodName + "} 调用次数：{" + counter.get() + "}");
        }
    }

    /**
     * 提供一个方法，用于获取方法调用次数的Map
     */
    public Map<String, AtomicInteger> getCounterMap() {
        return new ConcurrentHashMap<>(counterMap);
    }
}
